package impl

import (
	"adam2/internal/constants"
	"adam2/internal/dao/helper"
	"adam2/internal/domain"
	"adam2/internal/model"
	"adam2/internal/properties"
	"anubis-framework/pkg/io"
	"anubis-framework/pkg/util"
	"fmt"
	"math"
	"strconv"
	"strings"
	"time"
)

type Robot7StockFilterDaoImpl struct {
	*BaseDaoImpl
}

// 返回dao实现类
func GetRobot7StockFilterDaoImpl() *Robot7StockFilterDaoImpl {
	return &Robot7StockFilterDaoImpl{GetBaseDaoImpl()}
}

// 返回表名
func (_robot7StockFilterDaoImpl *Robot7StockFilterDaoImpl) FindTableName() string {
	return "ROBOT7_STOCK_FILTER"
}

// 清空ROBOT7_STOCK_FILTER表中的记录
func (_robot7StockFilterDaoImpl *Robot7StockFilterDaoImpl) TruncateTableRobotStockFilter() {
	io.Infoln("清空ROBOT7_STOCK_FILTER表中的记录")

	_robot7StockFilterDaoImpl.db.Exec("truncate table robot7_stock_filter")
}

// 从stock_transaction_data_all表中向robot7_stock_filter表中插入记录，不包括正在持有的股票
func (_robot7StockFilterDaoImpl *Robot7StockFilterDaoImpl) InsertBullStockCodeFromStockTransactionDataAll(date string) {
	io.Infoln("从stock_transaction_data_all表中向robot7_stock_filter表中插入记录，不包括正在持有的股票")

	_robot7StockFilterDaoImpl.db.Exec("insert into robot7_stock_filter(stock_code) "+
		"select distinct t1.code_ from stock_transaction_data_all t1 where t1.date_=to_date(?,'yyyy-mm-dd') "+
		"and t1.code_ not in("+
		"select t.stock_code from robot7_stock_transact_record t "+
		"where t.sell_date is null and t.sell_price is null and t.sell_amount is null)", date)
}

// 从etf_transaction_data表中向robot7_stock_filter表中插入记录（tendency_type为2，correlation250_with_avg_c_p不能为空，不包括正在持有的ETF）
func (_robot7StockFilterDaoImpl *Robot7StockFilterDaoImpl) InsertBullStockCodeFromEtfTransactionData(date string) {
	io.Infoln("从etf_transaction_data表中向robot7_stock_filter表中插入记录，不包括正在持有的ETF")

	_robot7StockFilterDaoImpl.db.Exec("insert into robot7_stock_filter(stock_code) "+
		"select distinct t1.code_ "+
		"from etf_transaction_data t1 "+
		"join etf_info ei on substr(ei.code_, 3, 8)=t1.code_ and ei.tendency_type=2 "+
		"where t1.date_=to_date(?,'yyyy-mm-dd') "+
		"and t1.correlation250_with_avg_c_p is not null "+
		"and t1.code_ not in(select t.stock_code from robot7_stock_transact_record t "+
		"where t.sell_date is null and t.sell_price is null and t.sell_amount is null)", date)
}

// 过滤条件：只保留成交量超过VOLUME_MA250或者成交额超过TURNOVER_MA250
func (_robot7StockFilterDaoImpl *Robot7StockFilterDaoImpl) FilterByVolumeOrTurnoverUp(date string) {
	io.Infoln("过滤条件：只保留成交量超过VOLUME_MA250或者成交额超过TURNOVER_MA250")

	_robot7StockFilterDaoImpl.db.Exec("delete from robot7_stock_filter where stock_code not in("+
		"select t.code_ from stock_transaction_data_all t where t.date_=to_date(?,'yyyy-mm-dd') "+
		"and (t.volume > t.volume_ma250 or t.turnover > t.turnover_ma250))",
		date)
}

// 过滤条件：只保留这个价格区间以内的股票
func (_robot7StockFilterDaoImpl *Robot7StockFilterDaoImpl) FilterByLessThanStockClosePrice(date string, closePriceBegin float64, closePriceEnd float64) {
	io.Infoln("过滤条件：只保留这个价格区间以内的股票")

	_robot7StockFilterDaoImpl.db.Exec("delete from robot7_stock_filter where stock_code not in("+
		"select t.code_ from stock_transaction_data_all t where t.date_=to_date(?,'yyyy-mm-dd') and t.close_price between ? and ?)",
		date, closePriceBegin, closePriceEnd)
}

// 过滤条件：只保留这个价格区间以内的ETF
func (_robot7StockFilterDaoImpl *Robot7StockFilterDaoImpl) FilterByLessThanEtfClosePrice(date string, closePriceBegin float64, closePriceEnd float64) {
	io.Infoln("过滤条件：只保留这个价格区间以内的ETF")

	_robot7StockFilterDaoImpl.db.Exec("delete from robot7_stock_filter where stock_code not in("+
		"select t.code_ from etf_transaction_data t where t.date_=to_date(?,'yyyy-mm-dd') and t.close_price between ? and ?)",
		date, closePriceBegin, closePriceEnd)
}

// 过滤条件：删除MACD死叉的股票
func (_robot7StockFilterDaoImpl *Robot7StockFilterDaoImpl) FilterByMacdGoldCross(currentDate string) {
	io.Infoln("过滤条件：删除MACD死叉的股票")

	_robot7StockFilterDaoImpl.db.Exec("delete from robot7_stock_filter t where t.stock_code in("+
		"select stda.code_ from stock_transaction_data_all stda "+
		"where stda.date_ = to_date(?, 'yyyy-mm-dd') and stda.dif<stda.dea)", currentDate)
}

// 过滤条件：股票交易日期之前的天数中，如果MACD持续处于金叉状态，则删除
func (_robot7StockFilterDaoImpl *Robot7StockFilterDaoImpl) FilterByMacdGoldCrossDateNumber(currentDate string, dateNumber int) {
	io.Infoln("过滤条件：股票交易日期之前的天数中，如果MACD持续处于金叉状态，则删除")

	// 查询robot7_stock_filter表的所有记录
	var robot7StockFilterArray model.Robot7StockFilterArray
	_robot7StockFilterDaoImpl.db.Raw("select * from robot7_stock_filter").Scan(&robot7StockFilterArray)

	if len(robot7StockFilterArray) != 0 {
		for _, robot7StockFilter := range robot7StockFilterArray {
			// 查找某只股票，在某个日期之前的若干条记录，并按照日期降序排列
			var stockTransactionDataAllArray model.StockTransactionDataAllArray
			_robot7StockFilterDaoImpl.db.Raw("select * from ("+
				"select * from stock_transaction_data_all t where t.code_=? and t.date_<to_date(?, 'yyyy-mm-dd') "+
				"order by t.date_ desc) "+
				"where rownum<=?",
				robot7StockFilter.StockCode, currentDate, dateNumber).Scan(&stockTransactionDataAllArray)

			if len(stockTransactionDataAllArray) != 0 {
				// 如果一段时间之内出现macd死叉，就不删除这条记录；否者删除
				var macdDeadross bool = false
				for i := 1; i < len(stockTransactionDataAllArray); i++ {
					if stockTransactionDataAllArray[i].Dif < stockTransactionDataAllArray[i].Dea {
						macdDeadross = true
						break
					}
				}
				if macdDeadross == false {
					_robot7StockFilterDaoImpl.db.Exec("delete from robot7_stock_filter t where t.stock_code = ?", robot7StockFilter.StockCode)
				}
			}
		}
	}
}

// 过滤条件：删除上一周，周线级别KD死叉的股票
func (_robot7StockFilterDaoImpl *Robot7StockFilterDaoImpl) FilterByLastStockWeekKDGoldCross(currentDate string) {
	io.Infoln("过滤条件：删除上一周，周线级别KD死叉的股票，日期[%s]", currentDate)

	var robot7StockFilterArray model.Robot7StockFilterArray
	_robot7StockFilterDaoImpl.db.Raw("select * from robot7_stock_filter").Scan(&robot7StockFilterArray)

	for _, robot7StockFilter := range robot7StockFilterArray {
		var stockWeek model.StockWeek
		_robot7StockFilterDaoImpl.db.Raw("select * from ("+
			"select * from stock_week sw "+
			"where sw.code_=? and sw.end_date<to_date(?,'yyyy-mm-dd') "+
			"order by sw.end_date desc) "+
			"where rownum<=1", robot7StockFilter.StockCode, currentDate).Scan(&stockWeek)

		if &stockWeek == nil {
			_robot7StockFilterDaoImpl.db.Exec("delete from robot7_stock_filter t where t.stock_code = ?", robot7StockFilter.StockCode)
		} else {
			if stockWeek.K < stockWeek.D {
				_robot7StockFilterDaoImpl.db.Exec("delete from robot7_stock_filter t where t.stock_code = ?", robot7StockFilter.StockCode)
			}
		}
	}
}

// 判断上个星期所有股票的平均KD是否是金叉，true表示是金叉，false表示不是金叉
func (_robot7StockFilterDaoImpl *Robot7StockFilterDaoImpl) IsLastStockWeekAverageKDGoldCross(currentDate string) bool {
	io.Infoln("判断上个星期所有股票的平均KD是否是金叉，true表示是金叉，false表示不是金叉，日期[%s]", currentDate)

	var stockWeek model.StockWeek
	_robot7StockFilterDaoImpl.db.Raw("select t1.begin_date BEGIN_DATE, t1.end_date END_DATE "+
		"from ("+
		"select * from stock_index_week t where t.code_='000001' and t.end_date<to_date(?,'yyyy-mm-dd') "+
		"order by t.end_date desc) t1 "+
		"where rownum<=1", currentDate).Scan(&stockWeek)

	_robot7StockFilterDaoImpl.db.Raw("select avg(t.k) K, avg(t.d) D "+
		"from stock_week t where t.begin_date>=? and t.end_date<=?",
		stockWeek.BeginDate, stockWeek.EndDate).Scan(&stockWeek)

	if stockWeek.K > stockWeek.D {
		return true
	} else {
		return false
	}
}

// 判断上一个交易日所有股票的平均MACD是否是金叉，true表示是金叉，false表示不是金叉
func (_robot7StockFilterDaoImpl *Robot7StockFilterDaoImpl) IsLastStockTransactionDataAllAverageMACDGoldCross(currentDate string) bool {
	io.Infoln("判断上一个交易日所有股票的平均MACD是否是金叉，true表示是金叉，false表示不是金叉，日期[%s]", currentDate)

	var stockTransactionDataAllAverage domain.StockTransactionDataAllAverage
	_robot7StockFilterDaoImpl.db.Raw("select to_char(t1.date_, 'yyyy-mm-dd') DATE_ "+
		"from ("+
		"select * from stock_index t where t.code_='000001' and t.date_<to_date(?,'yyyy-mm-dd') "+
		"order by t.date_ desc) t1 "+
		"where rownum<=1", currentDate).Scan(&stockTransactionDataAllAverage)

	_robot7StockFilterDaoImpl.db.Raw("select avg(t.dif) DIF, avg(t.dea) DEA "+
		"from stock_transaction_data_all t where t.date_=to_date(?,'yyyy-mm-dd') ",
		stockTransactionDataAllAverage.Date_).Scan(&stockTransactionDataAllAverage)

	if stockTransactionDataAllAverage.Dif > stockTransactionDataAllAverage.Dea {
		return true
	} else {
		return false
	}
}

// 判断当前交易日所有股票的平均MACD是否是金叉，true表示是金叉，false表示不是金叉
func (_robot7StockFilterDaoImpl *Robot7StockFilterDaoImpl) IsCurrentStockTransactionDataAllAverageMACDGoldCross(currentDate string) bool {
	io.Infoln("判断当前交易日所有股票的平均MACD是否是金叉，true表示是金叉，false表示不是金叉，日期[%s]", currentDate)

	var stockTransactionDataAllAverage domain.StockTransactionDataAllAverage
	_robot7StockFilterDaoImpl.db.Raw("select avg(t.dif) DIF, avg(t.dea) DEA "+
		"from stock_transaction_data_all t where t.date_=to_date(?,'yyyy-mm-dd') ",
		currentDate).Scan(&stockTransactionDataAllAverage)

	if stockTransactionDataAllAverage.Dif > stockTransactionDataAllAverage.Dea {
		return true
	} else {
		return false
	}
}

// 判断当前交易日所有股票的平均KD是否是金叉，true表示是金叉，false表示不是金叉
func (_robot7StockFilterDaoImpl *Robot7StockFilterDaoImpl) IsCurrentStockTransactionDataAllAverageKDGoldCross(currentDate string) bool {
	io.Infoln("判断当前交易日所有股票的平均KD是否是金叉，true表示是金叉，false表示不是金叉，日期[%s]", currentDate)

	var stockTransactionDataAllAverage domain.StockTransactionDataAllAverage
	_robot7StockFilterDaoImpl.db.Raw("select avg(t.k) K, avg(t.d) D "+
		"from stock_transaction_data_all t where t.date_=to_date(?,'yyyy-mm-dd') ",
		currentDate).Scan(&stockTransactionDataAllAverage)

	if stockTransactionDataAllAverage.K > stockTransactionDataAllAverage.D {
		return true
	} else {
		return false
	}
}

// 判断当前交易日所有股票的平均close_price是否金叉ma5，true表示是金叉，false表示不是金叉
func (_robot7StockFilterDaoImpl *Robot7StockFilterDaoImpl) IsCurrentStockTransactionDataAllAverageClosePriceGoldCrossMA5(currentDate string) bool {
	io.Infoln("判断当前交易日所有股票的平均close_price是否金叉ma5，true表示是金叉，false表示不是金叉，日期[%s]", currentDate)

	var stockTransactionDataAllAverage domain.StockTransactionDataAllAverage
	_robot7StockFilterDaoImpl.db.Raw("select avg(t.close_price) CLOSE_PRICE, avg(t.ma5) MA5 "+
		"from stock_transaction_data_all t where t.date_=to_date(?,'yyyy-mm-dd') ",
		currentDate).Scan(&stockTransactionDataAllAverage)

	if stockTransactionDataAllAverage.ClosePrice > stockTransactionDataAllAverage.Ma5 {
		return true
	} else {
		return false
	}
}

// 过滤条件：删除上一周最低价没有跌破周线级别布林带下轨的记录
func (_robot7StockFilterDaoImpl *Robot7StockFilterDaoImpl) FilterByLastLowestPriceDownBullDn(currentDate string) {
	io.Infoln("过滤条件：删除上一周最低价没有跌破周线级别布林带下轨的记录")

	var stockWeek model.StockWeek
	_robot7StockFilterDaoImpl.db.Raw("select t1.begin_date BEGIN_DATE, t1.end_date END_DATE "+
		"from ("+
		"select * from stock_index_week t where t.code_='000001' and t.end_date<to_date(?,'yyyy-mm-dd') "+
		"order by t.end_date desc) t1 "+
		"where rownum<=1", currentDate).Scan(&stockWeek)

	// 查询robot7_stock_filter表的所有记录
	var robot7StockFilterArray model.Robot7StockFilterArray
	_robot7StockFilterDaoImpl.db.Raw("select * from robot7_stock_filter").Scan(&robot7StockFilterArray)

	for _, robot7StockFilter := range robot7StockFilterArray {
		var stockWeekArray model.StockWeekArray
		_robot7StockFilterDaoImpl.db.Raw("select * from stock_week t "+
			"where t.begin_date>=? and t.end_date<=? and t.code_=?",
			stockWeek.BeginDate, stockWeek.EndDate, robot7StockFilter.StockCode).Scan(&stockWeekArray)

		if len(stockWeekArray) == 1 {
			if stockWeekArray[0].LowestPrice >= stockWeekArray[0].Dn {
				// 如果最低价没有跌破布林带下轨，则直接删除
				_robot7StockFilterDaoImpl.db.Exec("delete from robot7_stock_filter t where t.stock_code=?", robot7StockFilter.StockCode)
			}
		} else if len(stockWeekArray) > 1 {
			io.Fatalf("stock_week表中，code_为%s的记录，在日期%s和%s之间有多条记录",
				robot7StockFilter.StockCode, util.DateToString(stockWeek.BeginDate), util.DateToString(stockWeek.EndDate))
		} else if len(stockWeekArray) == 0 {
			// 如果没有周线级别的数据，则直接删除
			_robot7StockFilterDaoImpl.db.Exec("delete from robot7_stock_filter t where t.stock_code=?", robot7StockFilter.StockCode)
		} else {
			io.Fatalf("FilterByLastLowestPriceDownBullDn方法中出现未知错误")
		}
	}
}

// 过滤条件：删除除过权的股票
func (_robot7StockFilterDaoImpl *Robot7StockFilterDaoImpl) FilterByXr_stock(currentDate string, xrDateNumber int) {
	io.Infoln("过滤条件：删除除过权的股票")

	var robot7StockFilterArray model.Robot7StockFilterArray
	_robot7StockFilterDaoImpl.db.Raw("select * from robot7_stock_filter").Scan(&robot7StockFilterArray)

	var beginDate string
	var endDate string
	var num int = 0

	for _, robot7StockFilter := range robot7StockFilterArray {
		// 判断日期currentDate之前的xrDateNumber个交易日中是否有除权的股票
		_robot7StockFilterDaoImpl.db.Raw("select to_char(t4.date_, 'yyyy-mm-dd') from ("+
			"select * from ("+
			"select * from ("+
			"select * from stock_transaction_data_all t where t.code_=? and t.date_<=to_date(?,'yyyy-mm-dd') "+
			"order by t.date_ desc) "+
			"where rownum<=?) t3 "+
			"order by t3.date_ asc) t4 "+
			"where rownum<=1",
			robot7StockFilter.StockCode, currentDate, xrDateNumber).Scan(&beginDate)
		beginDateXr, _ := helper.FilterStockXr_stock(robot7StockFilter.StockCode, beginDate, currentDate)
		if beginDateXr == true {
			num++
			_robot7StockFilterDaoImpl.db.Exec("delete from robot7_stock_filter t where t.stock_code = ?", robot7StockFilter.StockCode)
		}

		// 判断日期currentDate之后的xrDateNumber个交易日中是否有除权的股票
		var modelBullShortLineUpArray model.ModelBullShortLineUpArray
		if robot7StockFilter.FilterType == 9 {
			_robot7StockFilterDaoImpl.db.Raw("select * from mdl_bull_short_line_up t "+
				"where t.stock_code = ? and t.buy_date = to_date(?, 'yyyy-mm-dd')",
				robot7StockFilter.StockCode, currentDate).Scan(&modelBullShortLineUpArray)
			endDateXr, _ := helper.FilterStockXr_stock(robot7StockFilter.StockCode, currentDate, util.DateToString(modelBullShortLineUpArray[0].SellDate))
			if endDateXr == true {
				num++
				_robot7StockFilterDaoImpl.db.Exec("delete from robot7_stock_filter t where t.stock_code = ?", robot7StockFilter.StockCode)
			}
		} else {
			// 未来的除权会以现金分红或股票分派的方式补偿，因此不能算是亏损，下面的代码不能注释掉
			_robot7StockFilterDaoImpl.db.Raw("select to_char(t4.date_, 'yyyy-mm-dd') from ("+
				"select * from ("+
				"select * from ("+
				"select * from stock_transaction_data_all t where t.code_=? and t.date_>=to_date(?,'yyyy-mm-dd') "+
				"order by t.date_ asc) "+
				"where rownum<=?) t3 "+
				"order by t3.date_ desc) t4 "+
				"where rownum<=1",
				robot7StockFilter.StockCode, currentDate, xrDateNumber).Scan(&endDate)
			endDateXr, _ := helper.FilterStockXr_stock(robot7StockFilter.StockCode, currentDate, endDate)
			if endDateXr == true {
				num++
				_robot7StockFilterDaoImpl.db.Exec("delete from robot7_stock_filter t where t.stock_code = ?", robot7StockFilter.StockCode)
			}
		}
	}

	io.Infoln("日期[%s]至[%s]之间，有[%d]只股票由于除权，已经从robot7_stock_filter表中删除", beginDate, endDate, num)
}

// 过滤条件：删除一字涨停板
func (_robot7StockFilterDaoImpl *Robot7StockFilterDaoImpl) FilterByOneWordLimitUp_stock(currentDate string) {
	io.Infoln("过滤条件：删除一字涨停板")

	var robot7StockFilterArray model.Robot7StockFilterArray
	_robot7StockFilterDaoImpl.db.Raw("select * from robot7_stock_filter").Scan(&robot7StockFilterArray)

	for _, robot7StockFilter := range robot7StockFilterArray {
		var stockTransactionDataAll model.StockTransactionDataAll
		_robot7StockFilterDaoImpl.db.Raw("select * from stock_transaction_data_all t "+
			"where t.code_ = ? and t.date_ = to_date(?, 'yyyy-mm-dd')",
			robot7StockFilter.StockCode, currentDate).Scan(&stockTransactionDataAll)

		// 是否涨停
		var limitUp bool = false

		// 在2020-08-24之前，并且当上涨幅度大于等于10%，并且开盘价和收盘价相等，就表示有可能是一字涨停板
		if util.Before(currentDate, constants.JUDGEMENT_DATE) && stockTransactionDataAll.ChangeRange >= 10 && stockTransactionDataAll.ClosePrice == stockTransactionDataAll.OpenPrice {
			limitUp = true
		}

		// 在2020-08-24之后，如果股票代码以300开头，并且上涨幅度大于等于20%，并且开盘价和收盘价相等，就表示有可能是一字涨停板
		if util.AfterOrEqual(currentDate, constants.JUDGEMENT_DATE) && strings.Compare(string(robot7StockFilter.StockCode[3]), "300") == 0 && stockTransactionDataAll.ChangeRange >= 20 && stockTransactionDataAll.ClosePrice == stockTransactionDataAll.OpenPrice {
			limitUp = true
		}

		// 在2020-08-24之后，如果股票代码不是300开头，并且上涨幅度大于等于10%，并且开盘价和收盘价相等，就表示有可能是一字涨停板
		if util.AfterOrEqual(currentDate, constants.JUDGEMENT_DATE) && strings.Compare(string(robot7StockFilter.StockCode[3]), "300") != 0 && stockTransactionDataAll.ChangeRange >= 10 && stockTransactionDataAll.ClosePrice == stockTransactionDataAll.OpenPrice {
			limitUp = true
		}

		// 如果是一字涨停板，则删除
		if limitUp {
			_robot7StockFilterDaoImpl.db.Exec("delete from robot7_stock_filter t where t.stock_code = ?", robot7StockFilter.StockCode)
		}
	}
}

// 过滤条件：由于有些涨停板是早上一开盘没多久就涨停的，实际中很难买到，因此这部分股票也删除掉
func (_robot7StockFilterDaoImpl *Robot7StockFilterDaoImpl) FilterByLimitUp_stock(currentDate string) {
	io.Infoln("过滤条件：由于有些涨停板是早上一开盘没多久就涨停的，实际中很难买到，因此这部分股票也删除掉")

	// 在2020-08-24之前，并且当上涨幅度大于等于10%
	if util.Before(currentDate, constants.JUDGEMENT_DATE) {
		_robot7StockFilterDaoImpl.db.Exec("delete from robot7_stock_filter t where t.stock_code in("+
			"select stda.code_ from stock_transaction_data_all stda "+
			"where stda.date_ = to_date(?, 'yyyy-mm-dd') and stda.change_range >= 10)", currentDate)
	}

	// 在2020-08-24之后，如果股票代码不以300开头，并且上涨幅度大于等于10%
	if util.AfterOrEqual(currentDate, constants.JUDGEMENT_DATE) {
		_robot7StockFilterDaoImpl.db.Exec("delete from robot7_stock_filter t where t.stock_code in("+
			"select stda.code_ from stock_transaction_data_all stda "+
			"where stda.date_ = to_date(?, 'yyyy-mm-dd') and stda.change_range >= 10 "+
			"and stda.code_ not like '300%')", currentDate)
	}

	// 在2020-08-24之后，如果股票代码是300开头，并且上涨幅度大于等于20%
	if util.AfterOrEqual(currentDate, constants.JUDGEMENT_DATE) {
		_robot7StockFilterDaoImpl.db.Exec("delete from robot7_stock_filter t where t.stock_code in("+
			"select stda.code_ from stock_transaction_data_all stda "+
			"where stda.date_ = to_date(?, 'yyyy-mm-dd') and stda.change_range >= 20 "+
			"and stda.code_ like '300%')", currentDate)
	}
}

// 过滤条件：删除除过权的ETF
func (_robot7StockFilterDaoImpl *Robot7StockFilterDaoImpl) FilterByXr_etf(currentDate string, xrDateNumber int) {
	io.Infoln("过滤条件：删除除过权的ETF")

	var robot7StockFilterArray model.Robot7StockFilterArray
	_robot7StockFilterDaoImpl.db.Raw("select * from robot7_stock_filter").Scan(&robot7StockFilterArray)

	var beginDate string
	var endDate string
	var num int = 0

	if len(robot7StockFilterArray) != 0 {
		for _, robot7StockFilter := range robot7StockFilterArray {
			// 判断日期currentDate之前的xrDateNumber个交易日中是否有除权的ETF
			//io.Infoln("开始判断ETF[%s]，在[%s]和[%s]之间是否有除权", robot7StockFilter.StockCode, beginDate, currentDate)
			_robot7StockFilterDaoImpl.db.Raw("select to_char(t4.date_, 'yyyy-mm-dd') from ("+
				"select * from ("+
				"select * from ("+
				"select * from etf_transaction_data t where t.code_=? and t.date_<=to_date(?,'yyyy-mm-dd') "+
				"order by t.date_ desc) "+
				"where rownum<=?) t3 "+
				"order by t3.date_ asc) t4 "+
				"where rownum<=1",
				robot7StockFilter.StockCode, currentDate, xrDateNumber).Scan(&beginDate)
			beginDateXr, _ := helper.FilterStockXr_etf(robot7StockFilter.StockCode, beginDate, currentDate)
			if beginDateXr == true {
				num++
				_robot7StockFilterDaoImpl.db.Exec("delete from robot7_stock_filter t where t.stock_code = ?", robot7StockFilter.StockCode)
			}

			// 判断日期currentDate之后的xrDateNumber个交易日中是否有除权的ETF
			var modelBullShortLineUpArray model.ModelBullShortLineUpArray
			if robot7StockFilter.FilterType == 9 {
				_robot7StockFilterDaoImpl.db.Raw("select * from mdl_etf_bull_short_line_up t "+
					"where t.etf_code = ? and t.buy_date = to_date(?, 'yyyy-mm-dd')",
					robot7StockFilter.StockCode, currentDate).Scan(&modelBullShortLineUpArray)
				endDateXr, _ := helper.FilterStockXr_etf(robot7StockFilter.StockCode, currentDate, util.DateToString(modelBullShortLineUpArray[0].SellDate))
				if endDateXr == true {
					num++
					_robot7StockFilterDaoImpl.db.Exec("delete from robot7_stock_filter t where t.stock_code = ?", robot7StockFilter.StockCode)
				}
			} else {
				_robot7StockFilterDaoImpl.db.Raw("select to_char(t4.date_, 'yyyy-mm-dd') from ("+
					"select * from ("+
					"select * from ("+
					"select * from etf_transaction_data t where t.code_=? and t.date_>=to_date(?,'yyyy-mm-dd') "+
					"order by t.date_ asc) "+
					"where rownum<=?) t3 "+
					"order by t3.date_ desc) t4 "+
					"where rownum<=1",
					robot7StockFilter.StockCode, currentDate, xrDateNumber).Scan(&endDate)
				endDateXr, _ := helper.FilterStockXr_etf(robot7StockFilter.StockCode, currentDate, endDate)
				if endDateXr == true {
					num++
					_robot7StockFilterDaoImpl.db.Exec("delete from robot7_stock_filter t where t.stock_code = ?", robot7StockFilter.StockCode)
				}
			}
		}
		io.Infoln("日期[%s]至[%s]之间，有[%d]只ETF由于除权，已经从robot7_stock_filter表中删除", beginDate, endDate, num)
	} else {
		io.Infoln("表robot7_stock_filter为空，不用删除除过权的ETF")
	}
}

// 过滤条件：删除一字涨停板
func (_robot7StockFilterDaoImpl *Robot7StockFilterDaoImpl) FilterByOneWordLimitUp_etf(currentDate string) {
	io.Infoln("过滤条件：删除一字涨停板")

	var robot7StockFilterArray model.Robot7StockFilterArray
	_robot7StockFilterDaoImpl.db.Raw("select * from robot7_stock_filter").Scan(&robot7StockFilterArray)

	// 是否涨停
	var limitUp bool = false

	for _, robot7StockFilter := range robot7StockFilterArray {
		var etfTransactionData model.EtfTransactionData
		_robot7StockFilterDaoImpl.db.Raw("select * from etf_transaction_data t "+
			"where t.code_ = ? and t.date_ = to_date(?, 'yyyy-mm-dd')",
			robot7StockFilter.StockCode, currentDate).Scan(&etfTransactionData)

		// 当上涨幅度大于等于10%，并且开盘价和收盘价相等，就表示有可能是一字涨停板
		if etfTransactionData.ChangeRange >= 10 && etfTransactionData.ClosePrice == etfTransactionData.OpenPrice {
			limitUp = true
		}

		// 如果是一字涨停板，则删除
		if limitUp {
			_robot7StockFilterDaoImpl.db.Exec("delete from robot7_stock_filter t where t.stock_code = ?", robot7StockFilter.StockCode)
		}
	}
}

// 过滤条件：由于有些涨停板是早上一开盘没多久就涨停的，实际中很难买到，因此这部分ETF也删除掉
func (_robot7StockFilterDaoImpl *Robot7StockFilterDaoImpl) FilterByLimitUp_etf(currentDate string) {
	io.Infoln("过滤条件：由于有些涨停板是早上一开盘没多久就涨停的，实际中很难买到，因此这部分ETF也删除掉")

	_robot7StockFilterDaoImpl.db.Exec("delete from robot7_stock_filter t where t.stock_code in("+
		"select stda.code_ from etf_transaction_data stda "+
		"where stda.date_ = to_date(?, 'yyyy-mm-dd') and stda.change_range >= 10)", currentDate)
}

// 过滤条件：判断用哪根均线作为牛熊线，牛熊线以下的股票都删除。如果在牛熊线以上则准备方差类型和方差值
func (_robot7StockFilterDaoImpl *Robot7StockFilterDaoImpl) FilterByBiasThreshold_stock(date string, biasThresholdTop float64, biasThresholdBottom float64) {
	io.Infoln("过滤条件：判断用哪根均线作为牛熊线，牛熊线以下的股票都删除。如果在牛熊线以上则准备方差类型和方差值")

	var stockTransactionDataAllArray model.StockTransactionDataAllArray
	_robot7StockFilterDaoImpl.db.Raw("select * from stock_transaction_data_all t "+
		"join robot7_stock_filter r on t.code_=r.stock_code "+
		"where t.date_=to_date(?,'yyyy-mm-dd')", date).Scan(&stockTransactionDataAllArray)

	for _, stockTransactionDataAll := range stockTransactionDataAllArray {
		// 表示牛熊线
		var bullShortLine float64

		if stockTransactionDataAll.Bias250 != 0 && stockTransactionDataAll.Bias250 <= biasThresholdTop && stockTransactionDataAll.Bias250 >= biasThresholdBottom {
			bullShortLine = stockTransactionDataAll.Ma250
			if stockTransactionDataAll.ClosePrice < bullShortLine {
				_robot7StockFilterDaoImpl.db.Exec("delete from robot7_stock_filter t where t.stock_code = ?", stockTransactionDataAll.Code)
			} else {
				_robot7StockFilterDaoImpl.db.Exec("update robot7_stock_filter t set t.variance_type=?, t.variance=? "+
					"where t.stock_code = ?", constants.VARIANCE250, stockTransactionDataAll.Variance250, stockTransactionDataAll.Code)
				//"where t.stock_code = ?", constants.Variance5, stockTransactionDataAll.Variance5, stockTransactionDataAll.Code)
			}
			continue
		}
		if stockTransactionDataAll.Bias120 != 0 && stockTransactionDataAll.Bias120 <= biasThresholdTop && stockTransactionDataAll.Bias120 >= biasThresholdBottom {
			bullShortLine = stockTransactionDataAll.Ma120
			if stockTransactionDataAll.ClosePrice < bullShortLine {
				_robot7StockFilterDaoImpl.db.Exec("delete from robot7_stock_filter t where t.stock_code = ?", stockTransactionDataAll.Code)
			} else {
				_robot7StockFilterDaoImpl.db.Exec("update robot7_stock_filter t set t.variance_type=?, t.variance=? "+
					"where t.stock_code = ?", constants.VARIANCE120, stockTransactionDataAll.Variance120, stockTransactionDataAll.Code)
				//"where t.stock_code = ?", constants.Variance5, stockTransactionDataAll.Variance5, stockTransactionDataAll.Code)
			}
			continue
		}
		if stockTransactionDataAll.Bias60 != 0 && stockTransactionDataAll.Bias60 <= biasThresholdTop && stockTransactionDataAll.Bias60 >= biasThresholdBottom {
			bullShortLine = stockTransactionDataAll.Ma60
			if stockTransactionDataAll.ClosePrice < bullShortLine {
				_robot7StockFilterDaoImpl.db.Exec("delete from robot7_stock_filter t where t.stock_code = ?", stockTransactionDataAll.Code)
			} else {
				_robot7StockFilterDaoImpl.db.Exec("update robot7_stock_filter t set t.variance_type=?, t.variance=? "+
					"where t.stock_code = ?", constants.VARIANCE60, stockTransactionDataAll.Variance60, stockTransactionDataAll.Code)
				//"where t.stock_code = ?", constants.Variance5, stockTransactionDataAll.Variance5, stockTransactionDataAll.Code)
			}
			continue
		}
		if stockTransactionDataAll.Bias20 != 0 && stockTransactionDataAll.Bias20 <= biasThresholdTop && stockTransactionDataAll.Bias20 >= biasThresholdBottom {
			bullShortLine = stockTransactionDataAll.Ma20
			if stockTransactionDataAll.ClosePrice < bullShortLine {
				_robot7StockFilterDaoImpl.db.Exec("delete from robot7_stock_filter t where t.stock_code = ?", stockTransactionDataAll.Code)
			} else {
				_robot7StockFilterDaoImpl.db.Exec("update robot7_stock_filter t set t.variance_type=?, t.variance=? "+
					"where t.stock_code = ?", constants.VARIANCE20, stockTransactionDataAll.Variance20, stockTransactionDataAll.Code)
				//"where t.stock_code = ?", constants.Variance5, stockTransactionDataAll.Variance5, stockTransactionDataAll.Code)
			}
			continue
		}
		if stockTransactionDataAll.Bias10 != 0 && stockTransactionDataAll.Bias10 <= biasThresholdTop && stockTransactionDataAll.Bias10 >= biasThresholdBottom {
			bullShortLine = stockTransactionDataAll.Ma10
			if stockTransactionDataAll.ClosePrice < bullShortLine {
				_robot7StockFilterDaoImpl.db.Exec("delete from robot7_stock_filter t where t.stock_code = ?", stockTransactionDataAll.Code)
			} else {
				_robot7StockFilterDaoImpl.db.Exec("update robot7_stock_filter t set t.variance_type=?, t.variance=? "+
					"where t.stock_code = ?", constants.VARIANCE10, stockTransactionDataAll.Variance10, stockTransactionDataAll.Code)
				//"where t.stock_code = ?", constants.Variance5, stockTransactionDataAll.Variance5, stockTransactionDataAll.Code)
			}
			continue
		}
		if stockTransactionDataAll.Bias5 != 0 && stockTransactionDataAll.Bias5 <= biasThresholdTop && stockTransactionDataAll.Bias5 >= biasThresholdBottom {
			bullShortLine = stockTransactionDataAll.Ma5
			if stockTransactionDataAll.ClosePrice < bullShortLine {
				_robot7StockFilterDaoImpl.db.Exec("delete from robot7_stock_filter t where t.stock_code = ?", stockTransactionDataAll.Code)
			} else {
				_robot7StockFilterDaoImpl.db.Exec("update robot7_stock_filter t set t.variance_type=?, t.variance=? "+
					"where t.stock_code = ?", constants.VARIANCE5, stockTransactionDataAll.Variance5, stockTransactionDataAll.Code)
			}
			continue
		}
		// 如果最后任何bias指标都无法确定哪一根均线可以作为牛熊线的话，则将前一个交易日的收盘价作为牛熊线。注意：现在数据库中last_close_price字段没有空值
		bullShortLine = stockTransactionDataAll.LastClosePrice
		if stockTransactionDataAll.ClosePrice < bullShortLine {
			_robot7StockFilterDaoImpl.db.Exec("delete from robot7_stock_filter t where t.stock_code = ?", stockTransactionDataAll.Code)
			continue
		} else {
			var avgClosePrice = (stockTransactionDataAll.LastClosePrice + stockTransactionDataAll.ClosePrice) / 2
			var variance2 = math.Pow(stockTransactionDataAll.LastClosePrice-avgClosePrice, 2) + math.Pow(stockTransactionDataAll.ClosePrice-avgClosePrice, 2)
			_robot7StockFilterDaoImpl.db.Exec("update robot7_stock_filter t set t.variance_type=?, t.variance=? "+
				"where t.stock_code = ?", constants.VARIANCE2, variance2, stockTransactionDataAll.Code)
			//"where t.stock_code = ?", constants.Variance5, stockTransactionDataAll.Variance5, stockTransactionDataAll.Code)
		}
	}
}

// 过滤条件：删除上周收盘价死叉周线级别MA5的股票
func (_robot7StockFilterDaoImpl *Robot7StockFilterDaoImpl) FilterByLastWeekCLosePriceGoldCrossLastWeekMA5(date string) {
	io.Infoln("过滤条件：删除上周收盘价死叉周线级别MA5的股票")

	var codeArray *[]string
	_robot7StockFilterDaoImpl.db.Raw("select distinct t.code_ from stock_transaction_data_all t "+
		"where t.date_=to_date(?,'yyyy-mm-dd')", date).Scan(&codeArray)

	for _, code := range *codeArray {
		var stockWeek *model.StockWeek
		_robot7StockFilterDaoImpl.db.Raw("select * from ("+
			"select * from stock_week t where t.code_=? order by t.end_date desc) t1 "+
			"where rownum<=1", code).Scan(&stockWeek)
		if stockWeek == nil {
			_robot7StockFilterDaoImpl.db.Exec("delete from robot7_stock_filter t where t.stock_code = ?", stockWeek.Code)
		} else {
			if stockWeek.ClosePrice < stockWeek.Ma5 {
				_robot7StockFilterDaoImpl.db.Exec("delete from robot7_stock_filter t where t.stock_code = ?", stockWeek.Code)
			}
		}
	}
}

// 过滤条件：判断用哪根均线作为牛熊线，牛熊线以下的ETF都删除。如果在牛熊线以上则准备相关系数
func (_robot7StockFilterDaoImpl *Robot7StockFilterDaoImpl) FilterByBiasThreshold_etf(date string, biasThresholdTop float64, biasThresholdBottom float64) {
	io.Infoln("过滤条件：判断用哪根均线作为牛熊线，牛熊线以下的ETF都删除。如果在牛熊线以上则准备相关系数")

	var etfTransactionDataArray model.EtfTransactionDataArray
	_robot7StockFilterDaoImpl.db.Raw("select * from etf_transaction_data t "+
		"join robot7_stock_filter r on t.code_=r.stock_code "+
		"join etf_info ei on substr(ei.code_, 3, 8)=t.code_ and ei.tendency_type=2 "+
		"where t.date_=to_date(?,'yyyy-mm-dd')", date).Scan(&etfTransactionDataArray)

	for _, etfTransactionData := range etfTransactionDataArray {
		// 表示牛熊线
		var bullShortLine float64

		// 应为etf_info表的code_字段是以SH开头的，因此此处需要删除SH
		etfTransactionData.Code = etfTransactionData.Code[2:8]

		if etfTransactionData.Bias250 != 0 && etfTransactionData.Bias250 <= biasThresholdTop && etfTransactionData.Bias250 >= biasThresholdBottom {
			bullShortLine = etfTransactionData.Ma250
			if etfTransactionData.ClosePrice < bullShortLine {
				_robot7StockFilterDaoImpl.db.Exec("delete from robot7_stock_filter t where t.stock_code = ?", etfTransactionData.Code)
			} else {
				_robot7StockFilterDaoImpl.db.Exec("update robot7_stock_filter t set t.correlation250_with_avg_c_p=? "+
					"where t.stock_code = ?", etfTransactionData.Correlation250WithAvgCP, etfTransactionData.Code)
				//io.Infoln("股票[%s]的牛熊线是MA250", stockTransactionDataAll.Code)
			}
			continue
		}
		if etfTransactionData.Bias120 != 0 && etfTransactionData.Bias120 <= biasThresholdTop && etfTransactionData.Bias120 >= biasThresholdBottom {
			bullShortLine = etfTransactionData.Ma120
			if etfTransactionData.ClosePrice < bullShortLine {
				_robot7StockFilterDaoImpl.db.Exec("delete from robot7_stock_filter t where t.stock_code = ?", etfTransactionData.Code)
			} else {
				_robot7StockFilterDaoImpl.db.Exec("update robot7_stock_filter t set t.correlation250_with_avg_c_p=? "+
					"where t.stock_code = ?", etfTransactionData.Correlation250WithAvgCP, etfTransactionData.Code)
				//io.Infoln("股票[%s]的牛熊线是MA120", stockTransactionDataAll.Code)
			}
			continue
		}
		if etfTransactionData.Bias60 != 0 && etfTransactionData.Bias60 <= biasThresholdTop && etfTransactionData.Bias60 >= biasThresholdBottom {
			bullShortLine = etfTransactionData.Ma60
			if etfTransactionData.ClosePrice < bullShortLine {
				_robot7StockFilterDaoImpl.db.Exec("delete from robot7_stock_filter t where t.stock_code = ?", etfTransactionData.Code)
			} else {
				_robot7StockFilterDaoImpl.db.Exec("update robot7_stock_filter t set t.correlation250_with_avg_c_p=? "+
					"where t.stock_code = ?", etfTransactionData.Correlation250WithAvgCP, etfTransactionData.Code)
				//io.Infoln("股票[%s]的牛熊线是MA60", stockTransactionDataAll.Code)
			}
			continue
		}
		if etfTransactionData.Bias20 != 0 && etfTransactionData.Bias20 <= biasThresholdTop && etfTransactionData.Bias20 >= biasThresholdBottom {
			bullShortLine = etfTransactionData.Ma20
			if etfTransactionData.ClosePrice < bullShortLine {
				_robot7StockFilterDaoImpl.db.Exec("delete from robot7_stock_filter t where t.stock_code = ?", etfTransactionData.Code)
			} else {
				_robot7StockFilterDaoImpl.db.Exec("update robot7_stock_filter t set t.correlation250_with_avg_c_p=? "+
					"where t.stock_code = ?", etfTransactionData.Correlation250WithAvgCP, etfTransactionData.Code)
				//io.Infoln("股票[%s]的牛熊线是MA20", stockTransactionDataAll.Code)
			}
			continue
		}
		if etfTransactionData.Bias10 != 0 && etfTransactionData.Bias10 <= biasThresholdTop && etfTransactionData.Bias10 >= biasThresholdBottom {
			bullShortLine = etfTransactionData.Ma10
			if etfTransactionData.ClosePrice < bullShortLine {
				_robot7StockFilterDaoImpl.db.Exec("delete from robot7_stock_filter t where t.stock_code = ?", etfTransactionData.Code)
			} else {
				_robot7StockFilterDaoImpl.db.Exec("update robot7_stock_filter t set t.correlation250_with_avg_c_p=? "+
					"where t.stock_code = ?", etfTransactionData.Correlation250WithAvgCP, etfTransactionData.Code)
				//io.Infoln("股票[%s]的牛熊线是MA10", stockTransactionDataAll.Code)
			}
			continue
		}
		if etfTransactionData.Bias5 != 0 && etfTransactionData.Bias5 <= biasThresholdTop && etfTransactionData.Bias5 >= biasThresholdBottom {
			bullShortLine = etfTransactionData.Ma5
			if etfTransactionData.ClosePrice < bullShortLine {
				_robot7StockFilterDaoImpl.db.Exec("delete from robot7_stock_filter t where t.stock_code = ?", etfTransactionData.Code)
			} else {
				_robot7StockFilterDaoImpl.db.Exec("update robot7_stock_filter t set t.correlation250_with_avg_c_p=? "+
					"where t.stock_code = ?", etfTransactionData.Correlation250WithAvgCP, etfTransactionData.Code)
				//io.Infoln("股票[%s]的牛熊线是MA5", stockTransactionDataAll.Code)
			}
			continue
		}
		// 如果最后任何bias指标都无法确定哪一根均线可以作为牛熊线的话，则将前一个交易日的收盘价作为牛熊线。注意：现在数据库中last_close_price字段没有空值
		bullShortLine = etfTransactionData.LastClosePrice
		if etfTransactionData.ClosePrice < bullShortLine {
			_robot7StockFilterDaoImpl.db.Exec("delete from robot7_stock_filter t where t.stock_code = ?", etfTransactionData.Code)
			continue
		} else {
			//var avgClosePrice = (etfTransactionData.LastClosePrice + etfTransactionData.ClosePrice) / 2
			//var variance2 = math.Pow(etfTransactionData.LastClosePrice-avgClosePrice, 2) + math.Pow(etfTransactionData.ClosePrice-avgClosePrice, 2)
			_robot7StockFilterDaoImpl.db.Exec("update robot7_stock_filter t set t.correlation250_with_avg_c_p=? "+
				"where t.stock_code = ?", etfTransactionData.Correlation250WithAvgCP, etfTransactionData.Code)
			//io.Infoln("股票[%s]的牛熊线是前一个交易日的收盘价", stockTransactionDataAll.Code)
		}
	}
}

// 确定仓位（是否使用动态仓位）。返回true表示买入股票，返回false表示不再买入股票
func (_robot7StockFilterDaoImpl *Robot7StockFilterDaoImpl) SetMaxHoldStockNumber_stock(date string) bool {
	io.Infoln("确定仓位（是否使用动态仓位）。返回true表示买入股票，返回false表示不再买入股票")

	// robot7_stock_filter表的记录数
	var robot7StockFilterCount float64
	_robot7StockFilterDaoImpl.db.Raw("select count(*) from robot7_stock_filter").Scan(&robot7StockFilterCount)
	// stock_transaction_data_all表的记录数
	var stockTransactionDataAllCount float64
	_robot7StockFilterDaoImpl.db.Raw("select count(*) from stock_transaction_data_all t where t.date_=to_date(?,'yyyy-mm-dd')",
		date).Scan(&stockTransactionDataAllCount)
	if robot7StockFilterCount == 0 || stockTransactionDataAllCount == 0 {
		io.Infoln("robot7_stock_filter表或stock_transaction_data_all表中的记录数为0，不再买入股票")

		// 向表robot7_account_log中插入数据
		var robot7AccountArray model.Robot7AccountArray
		_robot7StockFilterDaoImpl.db.Raw("select * from robot7_account").Scan(&robot7AccountArray)
		for _, robot7Account := range robot7AccountArray {
			//_robot7StockFilterDaoImpl.db.Exec("insert into robot7_account_log(DATE_, ROBOT_NAME, HOLD_STOCK_NUMBER, STOCK_ASSETS, "+
			//	"CAPITAL_ASSETS, TOTAL_ASSETS) "+
			//	"values(to_date(?, 'yyyy-mm-dd'), ?, ?, ?, ?, ?)",
			//	date, (*robot7Account).RobotName, (*robot7Account).HoldStockNumber,
			//	(*robot7Account).StockAssets, (*robot7Account).CapitalAssets, (*robot7Account).TotalAssets)
			_robot7StockFilterDaoImpl.db.Exec("insert into robot7_account_log(DATE_, ROBOT_NAME, HOLD_STOCK_NUMBER, STOCK_ASSETS, "+
				"CAPITAL_ASSETS, TOTAL_ASSETS, TOTAL_STAMP_DUTY, TOTAL_REGISTRATE_FEE_WHEN_BUY, TOTAL_COMMISSION_WHEN_BUY, "+
				"TOTAL_REGISTRATE_FEE_WHEN_SELL, TOTAL_COMMISSION_WHEN_SELL) "+
				"select to_date(?, 'yyyy-mm-dd'), t.ROBOT_NAME, t.HOLD_STOCK_NUMBER, t.STOCK_ASSETS, t.CAPITAL_ASSETS, t.TOTAL_ASSETS, t.TOTAL_STAMP_DUTY, "+
				"t.TOTAL_REGISTRATE_FEE_WHEN_BUY, t.TOTAL_COMMISSION_WHEN_BUY, t.TOTAL_REGISTRATE_FEE_WHEN_SELL, t.TOTAL_COMMISSION_WHEN_SELL "+
				"from robot7_account t where t.robot_name = ?",
				date, (*robot7Account).RobotName)
		}

		return false
	} else {
		var dynamicMaxHoldStockNumberInBull int = int((robot7StockFilterCount/stockTransactionDataAllCount)*10) + 1
		if dynamicMaxHoldStockNumberInBull < properties.Robot7Properties_.EnableTransactionHoldStockNumberLimit {
			io.Infoln("采用动态仓位，仓位为[%d]，不再买入股票", dynamicMaxHoldStockNumberInBull)

			// 向表robot7_account_log中插入数据
			var robot7AccountArray model.Robot7AccountArray
			_robot7StockFilterDaoImpl.db.Raw("select * from robot7_account").Scan(&robot7AccountArray)
			for _, robot7Account := range robot7AccountArray {
				//_robot7StockFilterDaoImpl.db.Exec("insert into robot7_account_log(DATE_, ROBOT_NAME, HOLD_STOCK_NUMBER, STOCK_ASSETS, "+
				//	"CAPITAL_ASSETS, TOTAL_ASSETS) "+
				//	"values(to_date(?, 'yyyy-mm-dd'), ?, ?, ?, ?, ?)",
				//	date, (*robot7Account).RobotName, (*robot7Account).HoldStockNumber,
				//	(*robot7Account).StockAssets, (*robot7Account).CapitalAssets, (*robot7Account).TotalAssets)
				_robot7StockFilterDaoImpl.db.Exec("insert into robot7_account_log(DATE_, ROBOT_NAME, HOLD_STOCK_NUMBER, STOCK_ASSETS, "+
					"CAPITAL_ASSETS, TOTAL_ASSETS, TOTAL_STAMP_DUTY, TOTAL_REGISTRATE_FEE_WHEN_BUY, TOTAL_COMMISSION_WHEN_BUY, "+
					"TOTAL_REGISTRATE_FEE_WHEN_SELL, TOTAL_COMMISSION_WHEN_SELL) "+
					"select to_date(?, 'yyyy-mm-dd'), t.ROBOT_NAME, t.HOLD_STOCK_NUMBER, t.STOCK_ASSETS, t.CAPITAL_ASSETS, t.TOTAL_ASSETS, t.TOTAL_STAMP_DUTY, "+
					"t.TOTAL_REGISTRATE_FEE_WHEN_BUY, t.TOTAL_COMMISSION_WHEN_BUY, t.TOTAL_REGISTRATE_FEE_WHEN_SELL, t.TOTAL_COMMISSION_WHEN_SELL "+
					"from robot7_account t where t.robot_name = ?",
					date, (*robot7Account).RobotName)
			}

			return false
		}
		if dynamicMaxHoldStockNumberInBull >= 10 {
			properties.Robot7Properties_.MaxHoldStockNumberInBull = 10
		} else {
			properties.Robot7Properties_.MaxHoldStockNumberInBull = dynamicMaxHoldStockNumberInBull
		}
		io.Infoln("采用动态仓位，仓位为[%d]", properties.Robot7Properties_.MaxHoldStockNumberInBull)
	}

	return true
}

// 确定仓位（使用动态仓位、熊市时交易ETF），设置参数MaxHoldStockNumberInShort并返回
func (_robot7StockFilterDaoImpl *Robot7StockFilterDaoImpl) SetMaxHoldStockNumber_etf(date string) int {
	io.Infoln("确定仓位（使用动态仓位、熊市时交易ETF")

	var count int
	_robot7StockFilterDaoImpl.db.Raw("select count(*) from etf_transaction_data t "+
		"where t.correlation250_with_avg_c_p is not null and t.date_=to_date(?,'yyyy-mm-dd')", date).Scan(&count)
	var maxHoldStockNumber_etf int = int(count/4) + 1
	if maxHoldStockNumber_etf > 10 {
		properties.Robot7Properties_.MaxHoldStockNumberInShort = 10
		return properties.Robot7Properties_.MaxHoldStockNumberInShort
	} else {
		properties.Robot7Properties_.MaxHoldStockNumberInShort = maxHoldStockNumber_etf
		return properties.Robot7Properties_.MaxHoldStockNumberInShort
	}
}

// 判断当前交易日，所有股票的平均价收盘价是否在牛熊线之上。true表示是，false表示否
func (_robot7StockFilterDaoImpl *Robot7StockFilterDaoImpl) IsUpBullShortLine(date string) bool {
	io.Infoln("判断当前交易日[%s]，所有股票的平均价收盘价是否在牛熊线之上。true表示是，false表示否", date)

	var averageClosePriceAndMaBullShortLineByBias *domain.AverageClosePriceAndMaAndTotalTurnoverBullShortLineByBias
	_robot7StockFilterDaoImpl.db.Raw("select to_char(t.date_, 'yyyy-mm-dd') DATE_, avg(t.close_price) AVERAGE_CLOSE_PRICE, avg(t.ma5) AVERAGE_MA5, "+
		"avg(t.ma10) AVERAGE_MA10, avg(t.ma20) AVERAGE_MA20, avg(t.ma60) AVERAGE_MA60, avg(t.ma120) AVERAGE_MA120, avg(t.ma250) AVERAGE_MA250, "+
		"avg(t.bias5) AVERAGE_BIAS5, avg(t.bias10) AVERAGE_BIAS10, avg(t.bias20) AVERAGE_BIAS20, avg(t.bias60) AVERAGE_BIAS60, "+
		"avg(t.bias120) AVERAGE_BIAS120, avg(t.bias250) AVERAGE_BIAS250 "+
		"from stock_transaction_data_all t "+
		"where t.date_ = to_date(?,'yyyy-mm-dd') group by t.date_", date).Scan(&averageClosePriceAndMaBullShortLineByBias)

	if &averageClosePriceAndMaBullShortLineByBias != nil {
		var topLimit float64 = properties.Robot7Properties_.BiasThresholdTop
		var bottomLimit float64 = properties.Robot7Properties_.BiasThresholdBottom
		var bullShortLine float64
		var averageClosePrice float64 = averageClosePriceAndMaBullShortLineByBias.AverageClosePrice
		var averageBias5 float64 = averageClosePriceAndMaBullShortLineByBias.AverageBias5
		var averageBias10 float64 = averageClosePriceAndMaBullShortLineByBias.AverageBias10
		var averageBias20 float64 = averageClosePriceAndMaBullShortLineByBias.AverageBias20
		var averageBias60 float64 = averageClosePriceAndMaBullShortLineByBias.AverageBias60
		var averageBias120 float64 = averageClosePriceAndMaBullShortLineByBias.AverageBias120
		var averageBias250 float64 = averageClosePriceAndMaBullShortLineByBias.AverageBias250

		//if averageClosePrice <= averageClosePriceAndMaBullShortLineByBias.AverageMa250 ||
		//	(averageClosePrice > averageClosePriceAndMaBullShortLineByBias.AverageMa250 &&
		//		averageClosePriceAndMaBullShortLineByBias.AverageMa250 > averageClosePriceAndMaBullShortLineByBias.AverageMa120) {
		if averageBias250 <= topLimit && averageBias250 >= bottomLimit {
			bullShortLine = averageClosePriceAndMaBullShortLineByBias.AverageMa250
		} else if averageBias120 <= topLimit && averageBias120 >= bottomLimit {
			bullShortLine = averageClosePriceAndMaBullShortLineByBias.AverageMa120
		} else if averageBias60 <= topLimit && averageBias60 >= bottomLimit {
			bullShortLine = averageClosePriceAndMaBullShortLineByBias.AverageMa60
		} else if averageBias20 <= topLimit && averageBias20 >= bottomLimit {
			bullShortLine = averageClosePriceAndMaBullShortLineByBias.AverageMa20
		} else if averageBias10 <= topLimit && averageBias10 >= bottomLimit {
			bullShortLine = averageClosePriceAndMaBullShortLineByBias.AverageMa10
		} else if averageBias5 <= topLimit && averageBias5 >= bottomLimit {
			bullShortLine = averageClosePriceAndMaBullShortLineByBias.AverageMa5
		} else {
			bullShortLine = averageClosePrice
		}
		//} else {
		//	if averageBias120 <= topLimit && averageBias120 >= bottomList {
		//		bullShortLine = averageClosePriceAndMaBullShortLineByBias.AverageMa120
		//	} else if averageBias60 <= topLimit && averageBias60 >= bottomList {
		//		bullShortLine = averageClosePriceAndMaBullShortLineByBias.AverageMa60
		//	} else if averageBias20 <= topLimit && averageBias20 >= bottomList {
		//		bullShortLine = averageClosePriceAndMaBullShortLineByBias.AverageMa20
		//	} else if averageBias10 <= topLimit && averageBias10 >= bottomList {
		//		bullShortLine = averageClosePriceAndMaBullShortLineByBias.AverageMa10
		//	} else if averageBias5 <= topLimit && averageBias5 >= bottomList {
		//		bullShortLine = averageClosePriceAndMaBullShortLineByBias.AverageMa5
		//	} else {
		//		bullShortLine = averageClosePrice
		//	}
		//}

		if averageClosePrice >= bullShortLine {
			io.Infoln("所有股票的平均价收盘价在牛熊线之上")
			return true
		} else {
			io.Infoln("所有股票的平均价收盘价不在牛熊线之上")
			return false
		}
	} else {
		io.Infoln("当前股票市场整体态势无法判断，按照所有股票的平均价收盘价在牛熊线之上处理")
		return true
	}
}

// 根据当前交易日，判断所有股票上一周的周线级别的平均K值是否比上上周的平均K值大，true表示是，false表示否
func (_robot7StockFilterDaoImpl *Robot7StockFilterDaoImpl) IsLastWeekAverageKGreatThanLastTwoWeekAverageK(date string) bool {
	io.Infoln("根据当前交易日[%s]，判断所有股票上一周的周线级别的平均K值是否比上上周的平均K值大，true表示是，false表示否", date)

	var stockIndexWeekArray model.StockIndexWeekArray
	_robot7StockFilterDaoImpl.db.Raw("select * from ("+
		"select * from stock_index_week t where t.code_='000001' and t.end_date<to_date(?,'yyyy-mm-dd') "+
		"order by t.end_date desc) "+
		"where rownum<=2", date).Scan(&stockIndexWeekArray)

	var lastWeekBeginDate time.Time = stockIndexWeekArray[0].BeginDate
	var lastWeekEndDate time.Time = stockIndexWeekArray[0].EndDate
	var lastTwoWeekBeginDate time.Time = stockIndexWeekArray[1].BeginDate
	var lastTwoWeekEndDate time.Time = stockIndexWeekArray[1].EndDate

	var lastWeekAverageK domain.LastWeekAverageK
	_robot7StockFilterDaoImpl.db.Raw("select "+
		"(select avg(t.k) from stock_week t where ?>=t.begin_date and ?<=t.end_date) LAST_WEEK_AVERAGE_K, "+
		"(select avg(t.k) from stock_week t where ?>=t.begin_date and ?<=t.end_date) LAST_TWO_WEEK_AVERAGE_K "+
		"from dual", lastWeekBeginDate, lastWeekEndDate, lastTwoWeekBeginDate, lastTwoWeekEndDate).Scan(&lastWeekAverageK)

	if lastWeekAverageK.LastWeekAverageK > lastWeekAverageK.LastTwoWeekAverageK {
		return true
	} else {
		return false
	}
}

// 根据当前交易日，判断所有股票上一周的周线级别的平均KD值是否金叉，true表示是，false表示否
func (_robot7StockFilterDaoImpl *Robot7StockFilterDaoImpl) IsLastWeekAverageKDGoldCross(date string) bool {
	io.Infoln("根据当前交易日[%s]，判断所有股票上一周的周线级别的平均KD值是否金叉，true表示是，false表示否", date)

	var stockIndexWeekArray model.StockIndexWeekArray
	_robot7StockFilterDaoImpl.db.Raw("select * from ("+
		"select * from stock_index_week t where t.code_='000001' and t.end_date<to_date(?,'yyyy-mm-dd') "+
		"order by t.end_date desc) "+
		"where rownum<=1", date).Scan(&stockIndexWeekArray)

	var lastWeekBeginDate time.Time = stockIndexWeekArray[0].BeginDate
	var lastWeekEndDate time.Time = stockIndexWeekArray[0].EndDate

	var lastWeekAverageKD domain.LastWeekAverageKD
	_robot7StockFilterDaoImpl.db.Raw("select avg(t.k) LAST_WEEK_AVERAGE_K, avg(t.d) LAST_WEEK_AVERAGE_D "+
		"from stock_week t "+
		"where ?>=t.begin_date and ?<=t.end_date",
		lastWeekBeginDate, lastWeekEndDate).Scan(&lastWeekAverageKD)

	if lastWeekAverageKD.LastWeekAverageK > lastWeekAverageKD.LastWeekAverageD {
		return true
	} else {
		return false
	}
}

// 根据当前交易日，判断所有股票上一周的平均收盘价是否金叉平均MA5，true表示是，false表示否
func (_robot7StockFilterDaoImpl *Robot7StockFilterDaoImpl) IsLastWeekAverageClosePriceGoldCrossLastWeekAverageMA5(date string) bool {
	io.Infoln("根据当前交易日[%s]，判断所有股票上一周的平均收盘价是否金叉平均MA5，true表示是，false表示否", date)

	var stockIndexWeekArray model.StockIndexWeekArray
	_robot7StockFilterDaoImpl.db.Raw("select * from ("+
		"select * from stock_index_week t where t.code_='000001' and t.end_date<to_date(?,'yyyy-mm-dd') "+
		"order by t.end_date desc) "+
		"where rownum<=1", date).Scan(&stockIndexWeekArray)

	var lastWeekBeginDate time.Time = stockIndexWeekArray[0].BeginDate
	var lastWeekEndDate time.Time = stockIndexWeekArray[0].EndDate

	var lastWeekAverageClosePriceAndLastWeekAverageMA5 domain.LastWeekAverageClosePriceAndLastWeekAverageMA5
	_robot7StockFilterDaoImpl.db.Raw("select avg(t.close_price) LAST_WEEK_AVERAGE_CLOSE_PRICE, avg(t.ma5) LAST_WEEK_AVERAGE_MA5 "+
		"from stock_week t "+
		"where ?>=t.begin_date and ?<=t.end_date",
		lastWeekBeginDate, lastWeekEndDate).Scan(&lastWeekAverageClosePriceAndLastWeekAverageMA5)

	if lastWeekAverageClosePriceAndLastWeekAverageMA5.LastWeekAverageClosePrice > lastWeekAverageClosePriceAndLastWeekAverageMA5.LastWeekAverageMa5 {
		return true
	} else {
		return false
	}
}

// 计算最近n个交易日，上涨家数的百分比的均值，如果大于等于50%则返回true，否则返回false
func (_robot7StockFilterDaoImpl *Robot7StockFilterDaoImpl) IsUpPercentageGTE50ByDateNumber(date string) bool {
	io.Infoln("计算最近[%s]个交易日，上涨家数的百分比的均值，如果大于等于百分之50则返回true，否则返回false",
		strconv.Itoa(properties.Robot7Properties_.UpPercentageDateNunber))

	var dateArray []time.Time
	_robot7StockFilterDaoImpl.db.Raw("select * from ("+
		"select distinct t.date_ from stock_transaction_data_all t"+
		" where t.date_<=to_date(?, 'yyyy-mm-dd') "+
		"order by t.date_ desc) where rownum<=?", date, properties.Robot7Properties_.UpPercentageDateNunber).Scan(&dateArray)

	var sumAverageUpPercentage float64 = 0.0
	for _, _date := range dateArray {
		var averageUpPercentage float64
		_robot7StockFilterDaoImpl.db.Raw("select ("+
			"select count(*) from stock_transaction_data_all t "+
			"where t.date_ = ? "+
			"and t.change_range>0)/("+
			"select count(*) from stock_transaction_data_all t "+
			"where t.date_ = ?)*100 "+
			"from dual", _date, _date).Scan(&averageUpPercentage)
		sumAverageUpPercentage = sumAverageUpPercentage + averageUpPercentage
	}
	var average float64 = sumAverageUpPercentage / float64(properties.Robot7Properties_.UpPercentageDateNunber)
	if average >= 50 {
		io.Infoln("最近[%s]个交易日，上涨家数的百分比的均值为[%s]，如果大于等于百分之50，返回true",
			strconv.Itoa(properties.Robot7Properties_.UpPercentageDateNunber), fmt.Sprintf("%f", average))
		return true
	} else {
		io.Infoln("最近[%s]个交易日，上涨家数的百分比的均值为[%s]，如果小于百分之50，返回false",
			strconv.Itoa(properties.Robot7Properties_.UpPercentageDateNunber), fmt.Sprintf("%f", average))
		return false
	}
}

// 过滤条件：更新robot7_stock_filter表：direction为1；filter_type为交易算法；accumulative_profit_rate累计收益。单位：元
func (_robot7StockFilterDaoImpl *Robot7StockFilterDaoImpl) UpdateRobotStockFilter_stock(date string) {
	io.Infoln("过滤条件：更新robot7_stock_filter表：direction为1；filter_type为交易算法；accumulative_profit_rate累计收益。单位：元")

	var robot7StockFilterArray model.Robot7StockFilterArray
	_robot7StockFilterDaoImpl.db.Raw("select * from robot7_stock_filter").Scan(&robot7StockFilterArray)

	for _, robot7StockFilter := range robot7StockFilterArray {
		// 最大收益率
		var maxProfitLoss float64 = -100
		// 最大收益率类型
		var maxProfitLossType int = 0
		// 最近五天收益率
		var lastFiveDayYieldRate float64 = 0.0

		// 计算最大收益率、最大收益率类型
		if properties.Robot7Properties_.TransactionStrategyInBull != 4 { // 如果不是收盘价金叉牛熊线算法
			var modelMacdGoldCrossArray model.ModelMacdGoldCrossArray
			_robot7StockFilterDaoImpl.db.Raw("select * from "+
				"(select * from mdl_macd_gold_cross t "+
				"where t.stock_code = ? and t.sell_date <= to_date(?, 'yyyy-mm-dd') "+
				"order by t.sell_date desc) t1 where rownum <= 1", robot7StockFilter.StockCode, date).Scan(&modelMacdGoldCrossArray)
			if len(modelMacdGoldCrossArray) != 0 && (*modelMacdGoldCrossArray[0]).AccumulativeProfitLoss > maxProfitLoss {
				maxProfitLoss = (*modelMacdGoldCrossArray[0]).AccumulativeProfitLoss
				maxProfitLossType = constants.MACD_GOLD_CROSS
			}
			var modelClosePriceMa5GoldCrossArray model.ModelClosePriceMa5GoldCrossArray
			_robot7StockFilterDaoImpl.db.Raw("select * from "+
				"(select * from mdl_close_price_ma5_gold_cross t "+
				"where t.stock_code = ? and t.sell_date <= to_date(?, 'yyyy-mm-dd') "+
				"order by t.sell_date desc) t1 where rownum <= 1", robot7StockFilter.StockCode, date).Scan(&modelClosePriceMa5GoldCrossArray)
			if len(modelClosePriceMa5GoldCrossArray) != 0 && (*modelClosePriceMa5GoldCrossArray[0]).AccumulativeProfitLoss > maxProfitLoss {
				maxProfitLoss = (*modelClosePriceMa5GoldCrossArray[0]).AccumulativeProfitLoss
				maxProfitLossType = constants.CLOSE_PRICE_MA5_GOLD_CROSS
			}
			var modelHeiKinAshiUpDownArray model.ModelHeiKinAshiUpDownArray
			_robot7StockFilterDaoImpl.db.Raw("select * from "+
				"(select * from mdl_hei_kin_ashi_up_down t "+
				"where t.stock_code = ? and t.sell_date <= to_date(?, 'yyyy-mm-dd') "+
				"order by t.sell_date desc) t1 where rownum <= 1", robot7StockFilter.StockCode, date).Scan(&modelHeiKinAshiUpDownArray)
			if len(modelHeiKinAshiUpDownArray) != 0 && (*modelHeiKinAshiUpDownArray[0]).AccumulativeProfitLoss > maxProfitLoss {
				maxProfitLoss = (*modelHeiKinAshiUpDownArray[0]).AccumulativeProfitLoss
				maxProfitLossType = constants.HEI_KIN_ASHI_UP
			}
			var modelKdGoldCrossArray model.ModelKdGoldCrossArray
			_robot7StockFilterDaoImpl.db.Raw("select * from "+
				"(select * from mdl_kd_gold_cross t "+
				"where t.stock_code = ? and t.sell_date <= to_date(?, 'yyyy-mm-dd') "+
				"order by t.sell_date desc) t1 where rownum <= 1", robot7StockFilter.StockCode, date).Scan(&modelKdGoldCrossArray)
			if len(modelKdGoldCrossArray) != 0 && (*modelKdGoldCrossArray[0]).AccumulativeProfitLoss > maxProfitLoss {
				maxProfitLoss = (*modelKdGoldCrossArray[0]).AccumulativeProfitLoss
				maxProfitLossType = constants.KD_GOLD_CROSS
			}
		} else { // 如果是收盘价金叉牛熊线算法
			var modelBullShortLineUpArray model.ModelBullShortLineUpArray
			_robot7StockFilterDaoImpl.db.Raw("select * from "+
				"(select * from mdl_bull_short_line_up t "+
				"where t.stock_code = ? and t.sell_date <= to_date(?, 'yyyy-mm-dd') "+
				"order by t.sell_date desc) t1 where rownum <= 1", robot7StockFilter.StockCode, date).Scan(&modelBullShortLineUpArray)
			if len(modelBullShortLineUpArray) != 0 && (*modelBullShortLineUpArray[0]).AccumulativeProfitLoss > maxProfitLoss {
				maxProfitLoss = (*modelBullShortLineUpArray[0]).AccumulativeProfitLoss
				maxProfitLossType = constants.CLOSE_PRICE_GOLD_CROSS_BULL_SHORT_LINE
			}
		}

		// 最近五天收益率
		var stockTransactionDataAllArray model.StockTransactionDataAllArray
		_robot7StockFilterDaoImpl.db.Raw("select * from ("+
			"select * from stock_transaction_data_all t where t.code_ = ? "+
			"and t.date_ <= to_date(?, 'yyyy-mm-dd') order by t.date_ desc) "+
			"where rownum<=5", robot7StockFilter.StockCode, date).Scan(&stockTransactionDataAllArray)
		var length int = len(stockTransactionDataAllArray)
		lastFiveDayYieldRate = (stockTransactionDataAllArray[length-1].ClosePrice - stockTransactionDataAllArray[0].ClosePrice) / stockTransactionDataAllArray[0].ClosePrice * 100

		if maxProfitLoss != -100 && maxProfitLossType != 0 && lastFiveDayYieldRate != 0.0 {
			// 更新
			_robot7StockFilterDaoImpl.db.Exec("update robot7_stock_filter t "+
				"set t.direction = 1, t.filter_type = ?, t.accumulative_profit_loss = ?, t.last_five_day_yield_rate = ? "+
				"where t.stock_code = ?", maxProfitLossType, maxProfitLoss, lastFiveDayYieldRate, robot7StockFilter.StockCode)
		} else {
			// 删除
			_robot7StockFilterDaoImpl.db.Exec("delete from robot7_stock_filter t "+
				"where t.stock_code = ?", robot7StockFilter.StockCode)
		}
	}
}

// 过滤条件：更新robot7_stock_filter表：direction为1；filter_type为交易算法；accumulative_profit_rate累计收益。单位：元
func (_robot7StockFilterDaoImpl *Robot7StockFilterDaoImpl) UpdateRobotStockFilter_etf(date string) {
	io.Infoln("过滤条件：更新robot7_stock_filter表：direction为1；filter_type为交易算法；accumulative_profit_rate累计收益。单位：元")

	var robot7StockFilterArray model.Robot7StockFilterArray
	_robot7StockFilterDaoImpl.db.Raw("select * from robot7_stock_filter").Scan(&robot7StockFilterArray)

	for _, robot7StockFilter := range robot7StockFilterArray {
		// 最大收益率
		var maxProfitLoss float64 = -100
		// 最大收益率类型
		var maxProfitLossType int = 0

		// 计算最大收益率、最大收益率类型
		var modelMacdGoldCrossArray model.ModelMacdGoldCrossArray
		if properties.Robot7Properties_.TransactionStrategyInShort != 4 { // 如果不是收盘价金叉牛熊线算法
			_robot7StockFilterDaoImpl.db.Raw("select * from "+
				"(select * from mdl_etf_macd_gold_cross t "+
				"where t.etf_code = ? and t.sell_date <= to_date(?, 'yyyy-mm-dd') and t.type_=1 "+
				"order by t.sell_date desc) t1 where rownum <= 1", robot7StockFilter.StockCode, date).Scan(&modelMacdGoldCrossArray)
			if len(modelMacdGoldCrossArray) != 0 && (*modelMacdGoldCrossArray[0]).AccumulativeProfitLoss > maxProfitLoss {
				maxProfitLoss = (*modelMacdGoldCrossArray[0]).AccumulativeProfitLoss
				maxProfitLossType = constants.MACD_GOLD_CROSS
			}
			var modelClosePriceMa5GoldCrossArray model.ModelClosePriceMa5GoldCrossArray
			_robot7StockFilterDaoImpl.db.Raw("select * from "+
				"(select * from mdl_etf_close_price_ma5_g_c t "+
				"where t.etf_code = ? and t.sell_date <= to_date(?, 'yyyy-mm-dd') and t.type_=1 "+
				"order by t.sell_date desc) t1 where rownum <= 1", robot7StockFilter.StockCode, date).Scan(&modelClosePriceMa5GoldCrossArray)
			if len(modelClosePriceMa5GoldCrossArray) != 0 && (*modelClosePriceMa5GoldCrossArray[0]).AccumulativeProfitLoss > maxProfitLoss {
				maxProfitLoss = (*modelClosePriceMa5GoldCrossArray[0]).AccumulativeProfitLoss
				maxProfitLossType = constants.CLOSE_PRICE_MA5_GOLD_CROSS
			}
			var modelHeiKinAshiUpDownArray model.ModelHeiKinAshiUpDownArray
			_robot7StockFilterDaoImpl.db.Raw("select * from "+
				"(select * from mdl_etf_hei_kin_ashi_down_up t "+
				"where t.etf_code = ? and t.sell_date <= to_date(?, 'yyyy-mm-dd') and t.type_=1 "+
				"order by t.sell_date desc) t1 where rownum <= 1", robot7StockFilter.StockCode, date).Scan(&modelHeiKinAshiUpDownArray)
			if len(modelHeiKinAshiUpDownArray) != 0 && (*modelHeiKinAshiUpDownArray[0]).AccumulativeProfitLoss > maxProfitLoss {
				maxProfitLoss = (*modelHeiKinAshiUpDownArray[0]).AccumulativeProfitLoss
				maxProfitLossType = constants.HEI_KIN_ASHI_UP
			}
			var modelKdGoldCrossArray model.ModelKdGoldCrossArray
			_robot7StockFilterDaoImpl.db.Raw("select * from "+
				"(select * from mdl_etf_kd_gold_cross t "+
				"where t.etf_code = ? and t.sell_date <= to_date(?, 'yyyy-mm-dd') and t.type_=1 "+
				"order by t.sell_date desc) t1 where rownum <= 1", robot7StockFilter.StockCode, date).Scan(&modelKdGoldCrossArray)
			if len(modelKdGoldCrossArray) != 0 && (*modelKdGoldCrossArray[0]).AccumulativeProfitLoss > maxProfitLoss {
				maxProfitLoss = (*modelKdGoldCrossArray[0]).AccumulativeProfitLoss
				maxProfitLossType = constants.KD_GOLD_CROSS
			}
		} else { // 如果是收盘价金叉牛熊线算法
			var modelEtfBullShortLineUpArray model.ModelEtfBullShortLineUpArray
			_robot7StockFilterDaoImpl.db.Raw("select * from "+
				"(select * from mdl_etf_bull_short_line_up t "+
				"where t.etf_code = ? and t.sell_date <= to_date(?, 'yyyy-mm-dd') "+
				"order by t.sell_date desc) t1 where rownum <= 1", robot7StockFilter.StockCode, date).Scan(&modelEtfBullShortLineUpArray)
			if len(modelEtfBullShortLineUpArray) != 0 && (*modelEtfBullShortLineUpArray[0]).AccumulativeProfitLoss > maxProfitLoss {
				maxProfitLoss = (*modelEtfBullShortLineUpArray[0]).AccumulativeProfitLoss
				maxProfitLossType = constants.CLOSE_PRICE_GOLD_CROSS_BULL_SHORT_LINE
			}
		}

		if maxProfitLoss != -100 && maxProfitLossType != 0 {
			// 更新
			_robot7StockFilterDaoImpl.db.Exec("update robot7_stock_filter t "+
				"set t.direction = 1, t.filter_type = ?, t.accumulative_profit_loss = ? "+
				"where t.stock_code = ?", maxProfitLossType, maxProfitLoss, robot7StockFilter.StockCode)
		} else {
			// 删除
			_robot7StockFilterDaoImpl.db.Exec("delete from robot7_stock_filter t "+
				"where t.stock_code = ?", robot7StockFilter.StockCode)
		}
	}
}

// 将robot7_stock_filter表的direction字段改为1
func (_robot7StockFilterDaoImpl *Robot7StockFilterDaoImpl) UpdateRobotStockFilterDirection_etf() {
	io.Infoln("将robot7_stock_filter表的direction字段改为1")
	_robot7StockFilterDaoImpl.db.Exec("update robot7_stock_filter t set t.direction = 1")
}

// 过滤条件：从robot7_stock_filter表中删除那些不是交易日的记录
func (_robot7StockFilterDaoImpl *Robot7StockFilterDaoImpl) FilterByBuyDate_stock(buyDate string) {
	io.Infoln("过滤条件：从robot7_stock_filter表中删除那些不是交易日的记录")

	var robot7StockFilterArray model.Robot7StockFilterArray
	_robot7StockFilterDaoImpl.db.Raw("select * from robot7_stock_filter").Scan(&robot7StockFilterArray)

	for _, robot7StockFilter := range robot7StockFilterArray {
		if robot7StockFilter.StockCode == "000034" {
			io.Infoln("-------------")
		}

		// 如果当前日期不是交易日，则跳过，并删除robot7_stock_filter中的记录
		var mdlMacdGoldCrossArray model.ModelMacdGoldCrossArray
		if robot7StockFilter.FilterType == 1 {
			_robot7StockFilterDaoImpl.db.Raw("select * from mdl_macd_gold_cross t "+
				"where t.stock_code = ? and t.buy_date = to_date(?, 'yyyy-mm-dd')",
				robot7StockFilter.StockCode, buyDate).Scan(&mdlMacdGoldCrossArray)
		}
		var mdlClosePriceMa5GoldCrossArray model.ModelClosePriceMa5GoldCrossArray
		if robot7StockFilter.FilterType == 3 {
			_robot7StockFilterDaoImpl.db.Raw("select * from mdl_close_price_ma5_gold_cross t "+
				"where t.stock_code = ? and t.buy_date = to_date(?, 'yyyy-mm-dd')",
				robot7StockFilter.StockCode, buyDate).Scan(&mdlClosePriceMa5GoldCrossArray)
		}
		var mdlHeiKinAshiUpDownArray model.ModelHeiKinAshiUpDownArray
		if robot7StockFilter.FilterType == 5 {
			_robot7StockFilterDaoImpl.db.Raw("select * from mdl_hei_kin_ashi_up_down t "+
				"where t.stock_code = ? and t.buy_date = to_date(?, 'yyyy-mm-dd')",
				robot7StockFilter.StockCode, buyDate).Scan(&mdlHeiKinAshiUpDownArray)
		}
		var mdlKdGoldCrossArray model.ModelKdGoldCrossArray
		if robot7StockFilter.FilterType == 7 {
			_robot7StockFilterDaoImpl.db.Raw("select * from mdl_kd_gold_cross t "+
				"where t.stock_code = ? and t.buy_date = to_date(?, 'yyyy-mm-dd')",
				robot7StockFilter.StockCode, buyDate).Scan(&mdlKdGoldCrossArray)
		}
		var mdlBullShortLineUpArray model.ModelBullShortLineUpArray
		if robot7StockFilter.FilterType == 9 {
			_robot7StockFilterDaoImpl.db.Raw("select * from mdl_bull_short_line_up t "+
				"where t.stock_code = ? and t.buy_date = to_date(?, 'yyyy-mm-dd')",
				robot7StockFilter.StockCode, buyDate).Scan(&mdlBullShortLineUpArray)
		}

		// 从robot7_stock_filter表中删除这条记录
		if len(mdlMacdGoldCrossArray) == 0 && len(mdlClosePriceMa5GoldCrossArray) == 0 &&
			len(mdlHeiKinAshiUpDownArray) == 0 && len(mdlKdGoldCrossArray) == 0 &&
			len(mdlBullShortLineUpArray) == 0 {
			_robot7StockFilterDaoImpl.db.Exec("delete from robot7_stock_filter t "+
				"where t.stock_code = ?", robot7StockFilter.StockCode)
		} else {
			//io.Infoln("股票[%s]准备交易", robot7StockFilter.StockCode)
		}
	}
}

// 过滤条件：从robot7_stock_filter表中删除那些不是交易日的记录
//func (_robot7StockFilterDaoImpl *Robot7StockFilterDaoImpl) FilterByBuyDate_etf(buyDate string) {
//	io.Infoln("过滤条件：从robot7_stock_filter表中删除那些不是交易日的记录")
//
//	var robot7StockFilterArray model.Robot7StockFilterArray
//	_robot7StockFilterDaoImpl.db.Raw("select * from robot7_stock_filter").Scan(&robot7StockFilterArray)
//
//	for _, robot7StockFilter := range robot7StockFilterArray {
//		// 如果当前日期不是交易日，则跳过，并删除robot7_stock_filter中的记录
//		var mdlMacdGoldCrossArray model.MdlMacdGoldCrossArray
//		if robot7StockFilter.FilterType == 1 {
//			_robot7StockFilterDaoImpl.db.Raw("select * from mdl_etf_macd_gold_cross t "+
//				"where t.etf_code = ? and t.buy_date = to_date(?, 'yyyy-mm-dd') and t.type_=1",
//				robot7StockFilter.StockCode, buyDate).Scan(&mdlMacdGoldCrossArray)
//		}
//		var mdlClosePriceMa5GoldCrossArray model.MdlClosePriceMa5GoldCrossArray
//		if robot7StockFilter.FilterType == 3 {
//			_robot7StockFilterDaoImpl.db.Raw("select * from mdl_etf_close_price_ma5_g_c t "+
//				"where t.etf_code = ? and t.buy_date = to_date(?, 'yyyy-mm-dd') and t.type_=1",
//				robot7StockFilter.StockCode, buyDate).Scan(&mdlClosePriceMa5GoldCrossArray)
//		}
//		var mdlHeiKinAshiUpDownArray model.MdlHeiKinAshiUpDownArray
//		if robot7StockFilter.FilterType == 5 {
//			_robot7StockFilterDaoImpl.db.Raw("select * from mdl_etf_hei_kin_ashi_down_up t "+
//				"where t.etf_code = ? and t.buy_date = to_date(?, 'yyyy-mm-dd') and t.type_=1",
//				robot7StockFilter.StockCode, buyDate).Scan(&mdlHeiKinAshiUpDownArray)
//		}
//		var mdlKdGoldCrossArray model.MdlKdGoldCrossArray
//		if robot7StockFilter.FilterType == 7 {
//			_robot7StockFilterDaoImpl.db.Raw("select * from mdl_etf_kd_gold_cross t "+
//				"where t.etf_code = ? and t.buy_date = to_date(?, 'yyyy-mm-dd') and t.type_=1",
//				robot7StockFilter.StockCode, buyDate).Scan(&mdlKdGoldCrossArray)
//		}
//		var mdlBullShortLineUpArray model.MdlBullShortLineUpArray
//		if robot7StockFilter.FilterType == 9 {
//			_robot7StockFilterDaoImpl.db.Raw("select * from mdl_bull_short_line_up t "+
//				"where t.stock_code = ? and t.buy_date = to_date(?, 'yyyy-mm-dd')",
//				robot7StockFilter.StockCode, buyDate).Scan(&mdlBullShortLineUpArray)
//		}
//
//		// 从robot7_stock_filter表中删除这条记录
//		if len(mdlMacdGoldCrossArray) == 0 && len(mdlClosePriceMa5GoldCrossArray) == 0 &&
//			len(mdlHeiKinAshiUpDownArray) == 0 && len(mdlKdGoldCrossArray) == 0 &&
//			len(mdlBullShortLineUpArray) == 0 {
//			_robot7StockFilterDaoImpl.db.Exec("delete from robot7_stock_filter t "+
//				"where t.stock_code = ?", robot7StockFilter.StockCode)
//		} else {
//			io.Infoln("")
//		}
//	}
//}

// 过滤条件：从robot7_stock_filter表中删除那些不是交易日的记录
func (_robot7StockFilterDaoImpl *Robot7StockFilterDaoImpl) FilterByBuyDate_etf(buyDate string) {
	io.Infoln("过滤条件：从robot7_stock_filter表中删除那些不是交易日的记录")

	var robot7StockFilterArray model.Robot7StockFilterArray
	_robot7StockFilterDaoImpl.db.Raw("select * from robot7_stock_filter").Scan(&robot7StockFilterArray)

	for _, robot7StockFilter := range robot7StockFilterArray {
		// 如果当前日期不是交易日，则跳过，并删除robot7_stock_filter中的记录
		//if domain.Robot7Config_.TransactionStrategyInShort != 4 {
		// mdl_etf_macd_gold_cross
		var mdlMacdGoldCrossArray model.ModelMacdGoldCrossArray
		if robot7StockFilter.FilterType == 1 {
			_robot7StockFilterDaoImpl.db.Raw("select * from mdl_etf_macd_gold_cross t "+
				"where t.etf_code = ? and t.buy_date = to_date(?, 'yyyy-mm-dd') and t.type_=1",
				robot7StockFilter.StockCode, buyDate).Scan(&mdlMacdGoldCrossArray)
		}
		// mdl_etf_close_price_ma5_g_c
		var mdlClosePriceMa5GoldCrossArray model.ModelClosePriceMa5GoldCrossArray
		if robot7StockFilter.FilterType == 3 {
			_robot7StockFilterDaoImpl.db.Raw("select * from mdl_etf_close_price_ma5_g_c t "+
				"where t.etf_code = ? and t.buy_date = to_date(?, 'yyyy-mm-dd') and t.type_=1",
				robot7StockFilter.StockCode, buyDate).Scan(&mdlClosePriceMa5GoldCrossArray)
		}
		// mdl_etf_hei_kin_ashi_down_up
		var mdlHeiKinAshiUpDownArray model.ModelHeiKinAshiUpDownArray
		if robot7StockFilter.FilterType == 5 {
			_robot7StockFilterDaoImpl.db.Raw("select * from mdl_etf_hei_kin_ashi_down_up t "+
				"where t.etf_code = ? and t.buy_date = to_date(?, 'yyyy-mm-dd') and t.type_=1",
				robot7StockFilter.StockCode, buyDate).Scan(&mdlHeiKinAshiUpDownArray)
		}
		// mdl_etf_kd_gold_cross
		var mdlKdGoldCrossArray model.ModelKdGoldCrossArray
		if robot7StockFilter.FilterType == 7 {
			_robot7StockFilterDaoImpl.db.Raw("select * from mdl_etf_kd_gold_cross t "+
				"where t.etf_code = ? and t.buy_date = to_date(?, 'yyyy-mm-dd') and t.type_=1",
				robot7StockFilter.StockCode, buyDate).Scan(&mdlKdGoldCrossArray)
		}
		//} else {
		// mdl_etf_bull_short_line_up
		var mdlEtfBullShortLineUpArray model.ModelEtfBullShortLineUpArray
		if robot7StockFilter.FilterType == 9 {
			_robot7StockFilterDaoImpl.db.Raw("select * from mdl_etf_bull_short_line_up t "+
				"where t.etf_code = ? and t.buy_date = to_date(?, 'yyyy-mm-dd')",
				robot7StockFilter.StockCode, buyDate).Scan(&mdlEtfBullShortLineUpArray)
		}
		//}

		// 从robot7_stock_filter表中删除这条记录
		if len(mdlMacdGoldCrossArray) == 0 && len(mdlClosePriceMa5GoldCrossArray) == 0 &&
			len(mdlHeiKinAshiUpDownArray) == 0 && len(mdlKdGoldCrossArray) == 0 &&
			len(mdlEtfBullShortLineUpArray) == 0 {
			_robot7StockFilterDaoImpl.db.Exec("delete from robot7_stock_filter t "+
				"where t.stock_code = ?", robot7StockFilter.StockCode)
		} /*else {
			io.Infoln("ETF[%s]准备交易", robot7StockFilter.StockCode)
		}*/
	}
}
